package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/hyperledger/fabric/core/chaincode/shim"
	pb "github.com/hyperledger/fabric/protos/peer"
	"strconv"
	"time"
)

/*
疫苗溯源
从疫苗生产运输的整个过程一共有三个角色生产商，运输商，金融商，医院
疫苗拥有唯一id，产地，还有过期时间，运输商三个角色需要对疫苗运输，保存的温度进行实时监控，一防止疫苗灭活
一旦疫苗运输保存中温度超出阈值，此疫苗状态为已失效
*/
const (
	OrderKeyPrefix           = "order"
	OrderStatusNew           = "新建（待确认）"
	OrderStatusConfirm       = "新建（已确认）"
	OrderStatusPayForAnother = "申请代付"
	OrderStatusPay           = "已付款（未核实）"
	OrderStatusPayed         = "已付款（已核实）"
	OrderStatusRefusePay     = "代付被拒"
	OrderStatusShip          = "已发货（未核实）"
	OrderstatusShiped        = "已发货（已核实）"
	OrderstatusReceiving     = "已收货"
	OrderStatusRepay         = "已还款（未核实）"
	OrderStatusRepayed       = "已还款（已核实）"
	SupplierKeyPrefix        = "supplier"
	FinancialOrgKeyPrefix    = "financialOrg"
	LogisticsKeyPrefix       = "logistics"
	HospitalKeyPrefix        = "hospital"
	VacunastatusPrefix       = "vacuna"
	VacunaStatus1            = "质量完好"
	VacunaStatus2            = "过期"
	VacunaStatus3            = "变质"
)

type Role struct { //角色结构体
	Id             string  `json:"id"`              //id
	Password       string  `json:"password"`        //密码
	Name           string  `json:"name"`            //企业名
	Address        string  `json:"address"`         //企业地址
	Phone          string  `json:"phone"`           //企业电话
	Email          string  `json:"email"`           //企业邮箱
	EnterpriseCode string  `json:"enterprise_code"` //企业统一社会信用代码
	Type           string  `json:"type"`            //企业类型
	Banlance       float64 `json:"banlance"`        //企业余额
	BankCard       string  `json:"bank_card"`       //企业卡号
}

type Vacuna struct { //疫苗结构体
	Id                string    `json:"id"`                 //疫苗id
	Name              string    `json:"name"`               //疫苗名称
	Productor         string    `json:"productor"`          //疫苗生产商
	FechaDeproducción time.Time `json:"fecha_deproducción"` //生产日期
	Status            string    `json:"status"`             //疫苗状态
	Description       string    `json:"description"`        //疫苗备注
	Propietario       string    `json:"propietario"`        //疫苗拥有者
	Value             float64   `json:"value"`              //疫苗价格
	Mintemperature    float64   `json:"mintemperature"`     //疫苗储存的最低温度
	Maxtemperature    float64   `json:"maxtemperature"`     //疫苗储存的最高温度
	Temperature       []Temp     `json:"temperature"`      //疫苗储存运输时的温度
}

type VacunaTransaction struct { //疫苗订单结构体
	Id                string    `json:"id"`                  // 单号
	Description       string    `json:"description"`         // 备注
	Value             float64   `json:"value"`               // 金额(单位为一分钱)
	Number            int64     `json:"number"`              // 疫苗数量
	ShipmentNumber    string    `json:"shipment_number"`     // 物流号
	PaymentTxNumber   string    `json:"payment_tx_number"`   // 付款转账号
	RepaymentTxNumber string    `json:"repayment_tx_number"` // 还款转账号
	Status            string    `json:"status"`              // 订单状态      ----`请使用上面const中的常量来标记订单状态`
	CreateDate        time.Time `json:"create_date"`         // 创建时间
	PaymentDate       time.Time `json:"payment_date"`        // 付款时间
	RepaymentDate     time.Time `json:"repayment_date"`      // 应还款时间
	RepayDate         time.Time `json:"repay_date"`          // 实际还款时间
	Supplier          string    `json:"supplier"`            // 供应商
	Company           string    `json:"company"`             // 采购商
	FinancialOrg      string    `json:"financial_org"`       // 金融机构
	Logística         string    `json:"logística"`           // 物流商
	Temperature       []Temp   `json:"temperature"`         // 运输保存中的温度数组
	VacunaId          []string  `json:"vacuna_id"`           // 此订单包含的疫苗id
}

type Temp struct {
	Id       string    `json:"id"`       //添加温度的角色id
	Roletype string    `json:"roletype"` //添加温度的角色类型
	Temps    []float64 `json:"temps"`    //温度数组
}
type Vacunacode struct {
}

/**
  @Author: dd
  @Date:   2020/5/13 16:22
  @Desc:   智能合约初始化，要求必须创建4个企业，分别为生产商、运输商、金融机构、医院 ,
  @Param:
  @Return:
**/
func (v Vacunacode) Init(stub shim.ChaincodeStubInterface) pb.Response {
	//	初始化四个用户，并初始化一个种类的疫苗
	id := []string{"10001", "10002", "10003", "10004"}
	password := []string{"123456", "456789", "147852", "258963"}
	name := []string{"白云药物公司", "顺丰速运", "工商银行", "北京市人民医院"}
	address := []string{"广州白云", "深圳", "广东中山", "北京市"}
	phone := []string{"15611245", "4513232456", "45212318546", "56454512"}
	email := []string{"451212123@qq.com", "1512312312@qq.com", "2324156@qq.com", "323132435@qq.com"}
	code := []string{"5412132454", "4132156431", "453212123", "1534321545"}
	roletype := []string{SupplierKeyPrefix, LogisticsKeyPrefix, FinancialOrgKeyPrefix, HospitalKeyPrefix}
	balance := []float64{5000, 2000, 50000, 60000}
	bankcard := []string{"323453211", "412124554543", "1212345421", "3212345132231"}
	for i := 0; i < len(id); i++ {
		role := Role{
			Id:             id[i],
			Password:       password[i],
			Name:           name[i],
			Address:        address[i],
			Phone:          phone[i],
			Email:          email[i],
			EnterpriseCode: code[i],
			Type:           roletype[i],
			Banlance:       balance[i],
			BankCard:       bankcard[i],
		}
		//反序列化创建组合键保存至账本
		roleByte, err := json.Marshal(role)
		if err != nil {
			return shim.Error(fmt.Sprintf("marshal error is %s", err))
		}
		roleKey, err := stub.CreateCompositeKey(roletype[i], []string{id[i]})
		if err != nil {
			return shim.Error("create key error")
		}
		if err := stub.PutState(roleKey, roleByte); err != nil {
			return shim.Error("putstate error")
		}
	}
	//	初始化两类疫苗
	Vacunaid := []string{"161051901", "161051902"}
	Vacunaname := []string{"新冠灭活疫苗", "小儿麻痹灭活疫苗"}
	Vacunapro := []string{"10001", "10001"}
	Vacunapropie := []string{"10001", "10001"}
	Vacunavalue := []float64{108.9, 20.9}
	Vacunamin := []float64{4, 10}
	Vacunamax := []float64{10, 15}
	for i := 0; i < len(Vacunaid); i++ {
		vacu := Vacuna{
			Id:                Vacunaid[i],
			Name:              Vacunaname[i],
			Productor:         Vacunapro[i],
			FechaDeproducción: time.Now(),
			Status:            VacunaStatus1,
			Description:       "",
			Propietario:       Vacunapropie[i],
			Value:             Vacunavalue[i],
			Mintemperature:    Vacunamin[i],
			Maxtemperature:    Vacunamax[i],
			Temperature:       nil,
		}
		vacuByte, err := json.Marshal(vacu)
		if err != nil {
			return shim.Error("marshal error")
		}
		vacuKey, err := stub.CreateCompositeKey(VacunastatusPrefix, []string{Vacunaid[i]})
		if err != nil {
			return shim.Error("create key error ")
		}
		if err := stub.PutState(vacuKey, vacuByte); err != nil {
			return shim.Error("putstate error ")
		}
	}
	return shim.Success([]byte("初始化成功"))
}

func (v Vacunacode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
	fun, args := stub.GetFunctionAndParameters()
	switch fun {
	case "QueryRole": //查询角色
		return QueryRole(stub, args)
	case "createRole": //新建角色
		return createRole(stub, args)
	case "createVacuna": //新建疫苗
		return createVacuna(stub, args)
	case "createOrder": //新建订单
		return createOrder(stub, args)
	case "confirmOrder": //确认订单
		return confirmOrder(stub, args)
	case "applypayOrder": //申请代付
		return applypayOrder(stub, args)
	case "payOrder": //金融机构代付
		return payOrder(stub, args)
	case "refusepayOrder": //拒绝代付
		return refusepayOrder(stub, args)
	case "confirmpay": //生产商确认收款
		return confirmpay(stub, args)
	case "updateOrder": //生产商转接给物流商发货
		return updateOrder(stub, args)
	case "confirmOrderTake": //采购商确认发货
		return confirmOrderTake(stub, args)
	case "addTemperature": //添加温度
		return addTemperature(stub, args)
	case "confirmReceiving": //确认收货
		return confirmReceiving(stub, args)
	case "repayOrder": //买家还款
		return repayOrder(stub, args)
	case "confirmrepay": //金融机构确认收款
		return confirmrepay(stub, args)
	case "timeoutpay": //自动还款
		return timeoutpay(stub, args)
	case "queryOrder": //查询订单
		return queryOrder(stub, args)
	case "queryRoleVacunas": //查询名下疫苗
		return queryRoleVacunas(stub, args)
	case "queryVacuna": //查询单个疫苗
		return queryVacuna(stub, args)
	case "queryOrderHistory": //查询订单历史
		return queryOrderHistory(stub, args)
	}
	return shim.Error("not find function")
}

func QueryRole(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	//查询角色传入角色id 及类型
	filedres := Vacunafiledchecking(stub, args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	//	根据传入的id及类型创建组合键查询角色
	roleKey, err := stub.CreateCompositeKey(args[1], []string{args[0]})
	if err != nil {
		return shim.Error("create key error")
	}
	roleByte, err := stub.GetState(roleKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(roleByte) == 0 {
		return shim.Error("not find role")
	}
	return shim.Success(roleByte)
}

func createRole(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	//传入一个角色结构体
	filedres := Vacunafiledchecking(stub, args, 1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	var role Role
	if err := json.Unmarshal([]byte(args[0]), &role); err != nil {
		return shim.Error("unmarshal error")
	}
	//验证创建角色字段是否有空
	if role.Id == "" || role.Password == "" || role.Name == "" || role.EnterpriseCode == "" || role.Phone == "" || role.Type == "" {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "若干角色字段为空",
			Payload: nil,
		}
	}
	roleByte, err := json.Marshal(role)
	if err != nil {
		return shim.Error("marshal error ")
	}
	roleKey, err := stub.CreateCompositeKey(role.Type, []string{role.Id})
	if err != nil {
		return shim.Error("create key error ")
	}
	if err := stub.PutState(roleKey, roleByte); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(roleByte)
}

func createVacuna(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	//新建一个疫苗，传入一个疫苗结构体
	filedres := Vacunafiledchecking(stub, args, 1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	var vacuna Vacuna
	if err := json.Unmarshal([]byte(args[0]), &vacuna); err != nil {
		return shim.Error("unmarshal error")
	}
	//判断传入字段是否为空
	filedargs := []string{vacuna.Id, vacuna.Name, vacuna.Status, vacuna.Propietario, vacuna.Productor}
	filedres = Vacunafiledchecking(stub, filedargs, len(filedargs))
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	if vacuna.Value < 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "疫苗金额错误",
			Payload: nil,
		}
	}
	//判断完成后反序列化保存至账本
	vacuByte, err := json.Marshal(vacuna)
	if err != nil {
		return shim.Error("marshal error ")
	}
	vacuKey, err := stub.CreateCompositeKey(VacunastatusPrefix, []string{vacuna.Id})
	if err != nil {
		return shim.Error("create key error")
	}
	if err := stub.PutState(vacuKey, vacuByte); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(vacuByte)
}

func createOrder(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	//创建订单，传入订单结构体
	filedres := Vacunafiledchecking(stub, args, 1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	var order VacunaTransaction
	if err := json.Unmarshal([]byte(args[0]), &order); err != nil {
		return shim.Error("unmarshal error")
	}
	//判断传入字段是否为空
	filedargs := []string{order.Id, order.Company, order.Supplier}
	filedres = Vacunafiledchecking(stub, filedargs, len(filedargs))
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	//判断购买的疫苗数量是否相同及疫苗id是否为空
	filedres = Vacunafiledchecking(stub, order.VacunaId, int(order.Number))
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	//判断金额数量
	if order.Value < 0 || order.Number <= 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "疫苗数量或金额错误",
			Payload: nil,
		}
	}
	//判断完成修改订单状态
	order.Status = OrderStatusNew
	order.CreateDate = time.Now()
	//反序列化保存至账本
	orderKey, err := stub.CreateCompositeKey(OrderKeyPrefix, []string{order.Id})
	if err != nil {
		return shim.Error("create key error")
	}
	orderByte, err := json.Marshal(order)
	if err != nil {
		return shim.Error("marshal error ")
	}
	if err := stub.PutState(orderKey, orderByte); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(orderByte)
}

func confirmOrder(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	//供应商确认订单，传入，以及订单id 供应商的id
	filedres := Vacunafiledchecking(stub, args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	//通过订单id查询订单
	orderKey, err := stub.CreateCompositeKey(OrderKeyPrefix, []string{args[0]})
	if err != nil {
		return shim.Error("create key error")
	}
	orderByte, err := stub.GetState(orderKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(orderByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未查询到相关订单",
			Payload: nil,
		}
	}
	//反序列化
	var order VacunaTransaction
	if err := json.Unmarshal(orderByte, &order); err != nil {
		return shim.Error("unmarshal error")
	}
	if order.Status != OrderStatusNew {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "订单状态出错",
			Payload: nil,
		}
	}
	if order.Supplier != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "无权修改此订单",
			Payload: nil,
		}
	}
	order.Status = OrderStatusConfirm
	orderByte1, err := json.Marshal(order)
	if err != nil {
		return shim.Error("marshal error ")
	}
	if err := stub.PutState(orderKey, orderByte1); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(orderByte1)
}

func applypayOrder(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	//用户申请代付，传入订单结构体，取订单id、采购商id、代付商id、承诺还款时间
	filedres := Vacunafiledchecking(stub, args, 1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	var order VacunaTransaction
	if err := json.Unmarshal([]byte(args[0]), &order); err != nil {
		return shim.Error("unmarshal error")
	}
	//判断传入字段是否为空
	filedargs := []string{order.Id, order.Company, order.FinancialOrg}
	filedres = Vacunafiledchecking(stub, filedargs, len(filedargs))
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	//判断承诺还款日期是否大于当前时间
	if order.RepaymentDate.Unix() > time.Now().Unix() {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "应还款时间大于当前时间",
			Payload: nil,
		}
	}
	//查询订单
	orderKey, err := stub.CreateCompositeKey(OrderKeyPrefix, []string{order.Id})
	if err != nil {
		return shim.Error("create key error")
	}
	orderByte, err := stub.GetState(orderKey)
	if err != nil {
		return shim.Error("getstate error")
	}
	if len(orderByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "为查询到订单",
			Payload: nil,
		}
	}
	var order1 VacunaTransaction
	if err := json.Unmarshal(orderByte, &order1); err != nil {
		return shim.Error("unmarshal error ")
	}
	if order1.Status != OrderStatusConfirm &&order1.Status!=OrderStatusRefusePay{
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "订单状态出错",
			Payload: nil,
		}
	}
	if order1.Company != order.Company {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "无权修改此订单",
			Payload: nil,
		}
	}
	//跟新订单
	order1.Status = OrderStatusPayForAnother
	order1.FinancialOrg=order.FinancialOrg
	order1.RepaymentDate = order.RepaymentDate
	orderByte1, err := json.Marshal(order1)
	if err != nil {
		return shim.Error("marshal error")
	}
	if err := stub.PutState(orderKey, orderByte1); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(orderByte1)
}

//{id:string,PaymentTxNumber:string,financial_org:string,payment_date:time.Time}
func payOrder(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := Vacunafiledchecking(stub, args, 1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	var order VacunaTransaction
	if err := json.Unmarshal([]byte(args[0]), &order); err != nil {
		return shim.Error("unmarshal error")
	}
	//判断传入字段是否为空
	filedargs := []string{order.Id, order.PaymentTxNumber, order.FinancialOrg}
	filedres = Vacunafiledchecking(stub, filedargs, len(filedargs))
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	//查询订单
	orderKey, err := stub.CreateCompositeKey(OrderKeyPrefix, []string{order.Id})
	if err != nil {
		return shim.Error("create key error")
	}
	orderByte, err := stub.GetState(orderKey)
	if err != nil {
		return shim.Error("getstate error")
	}
	if len(orderByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "为查询到订单",
			Payload: nil,
		}
	}
	var order1 VacunaTransaction
	if err := json.Unmarshal(orderByte, &order1); err != nil {
		return shim.Error("unmarshal error ")
	}
	if order1.Status != OrderStatusPayForAnother && order1.Status != OrderStatusRefusePay {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "订单状态出错",
			Payload: nil,
		}
	}
	if order1.FinancialOrg != order.FinancialOrg {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "无权修改此订单",
			Payload: nil,
		}
	}
	//执行转账
	transferAccountsres := outtoin(stub, order1.FinancialOrg, FinancialOrgKeyPrefix, order1.Supplier, SupplierKeyPrefix, order1.Value)
	if transferAccountsres.Status != shim.OK {
		return pb.Response{
			Status:  transferAccountsres.Status,
			Message: transferAccountsres.Message,
			Payload: nil,
		}
	}
	//转账成功跟新订单
	order1.Status = OrderStatusPay
	order1.PaymentTxNumber = order.PaymentTxNumber
	order1.PaymentDate = order.PaymentDate
	orderByte1, err := json.Marshal(order1)
	if err != nil {
		return shim.Error("marshal error")
	}
	if err := stub.PutState(orderKey, orderByte1); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(orderByte1)
}

//@Param:  {id:string,description:string,financial_org:string}
func refusepayOrder(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	//拒绝代付
	filedres := Vacunafiledchecking(stub, args, 1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	var order VacunaTransaction
	if err := json.Unmarshal([]byte(args[0]), &order); err != nil {
		return shim.Error("unmarshal error")
	}
	//判断传入字段是否为空
	filedargs := []string{order.Id, order.Description, order.FinancialOrg}
	filedres = Vacunafiledchecking(stub, filedargs, len(filedargs))
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	//查询订单
	orderKey, err := stub.CreateCompositeKey(OrderKeyPrefix, []string{order.Id})
	if err != nil {
		return shim.Error("create key error")
	}
	orderByte, err := stub.GetState(orderKey)
	if err != nil {
		return shim.Error("getstate error")
	}
	if len(orderByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "为查询到订单",
			Payload: nil,
		}
	}
	var order1 VacunaTransaction
	if err := json.Unmarshal(orderByte, &order1); err != nil {
		return shim.Error("unmarshal error ")
	}
	if order1.Status != OrderStatusPayForAnother && order1.Status != OrderStatusRefusePay {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "订单状态出错",
			Payload: nil,
		}
	}
	if order1.FinancialOrg != order.FinancialOrg {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "无权修改此订单",
			Payload: nil,
		}
	}
	order1.Status = OrderStatusRefusePay
	order1.Description = order.Description
	orderByte1, err := json.Marshal(order1)
	if err != nil {
		return shim.Error("marshal error")
	}
	if err := stub.PutState(orderKey, orderByte1); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(orderByte1)
}

func confirmpay(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	//生产商确认收款，传入  订单id 供应商id
	filedres := Vacunafiledchecking(stub, args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	//通过订单id查询订单
	orderKey, err := stub.CreateCompositeKey(OrderKeyPrefix, []string{args[0]})
	if err != nil {
		return shim.Error("create key error")
	}
	orderByte, err := stub.GetState(orderKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(orderByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未查询到相关订单",
			Payload: nil,
		}
	}
	//反序列化
	var order VacunaTransaction
	if err := json.Unmarshal(orderByte, &order); err != nil {
		return shim.Error("unmarshal error")
	}
	if order.Status != OrderStatusPay {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "订单状态出错",
			Payload: nil,
		}
	}
	if order.Supplier != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "无权修改此订单",
			Payload: nil,
		}
	}
	order.Status = OrderStatusPayed
	orderByte1, err := json.Marshal(order)
	if err != nil {
		return shim.Error("marshal error ")
	}
	if err := stub.PutState(orderKey, orderByte1); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(orderByte1)
}

// 传入订单id 生产商id 物流商id 物流单号
func updateOrder(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := Vacunafiledchecking(stub, args, 4)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	//通过订单id查询订单
	orderKey, err := stub.CreateCompositeKey(OrderKeyPrefix, []string{args[0]})
	if err != nil {
		return shim.Error("create key error")
	}
	orderByte, err := stub.GetState(orderKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(orderByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未查询到相关订单",
			Payload: nil,
		}
	}
	//反序列化
	var order VacunaTransaction
	if err := json.Unmarshal(orderByte, &order); err != nil {
		return shim.Error("unmarshal error")
	}
	if order.Status != OrderStatusPayed {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "订单状态出错",
			Payload: nil,
		}
	}
	if order.Supplier != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "无权修改此订单",
			Payload: nil,
		}
	}
	order.Status = OrderStatusShip
	order.Logística = args[2]
	order.ShipmentNumber = args[3]
	orderByte1, err := json.Marshal(order)
	if err != nil {
		return shim.Error("marshal error ")
	}
	if err := stub.PutState(orderKey, orderByte1); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(orderByte1)
}

//采购商确认发货 传入订单id 采购商id
func confirmOrderTake(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := Vacunafiledchecking(stub, args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	//通过订单id查询订单
	orderKey, err := stub.CreateCompositeKey(OrderKeyPrefix, []string{args[0]})
	if err != nil {
		return shim.Error("create key error")
	}
	orderByte, err := stub.GetState(orderKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(orderByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未查询到相关订单",
			Payload: nil,
		}
	}
	//反序列化
	var order VacunaTransaction
	if err := json.Unmarshal(orderByte, &order); err != nil {
		return shim.Error("unmarshal error")
	}
	if order.Status != OrderStatusShip {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "订单状态出错",
			Payload: nil,
		}
	}
	if order.Company != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "无权修改此订单",
			Payload: nil,
		}
	}
	order.Status = OrderstatusShiped
	orderByte1, err := json.Marshal(order)
	if err != nil {
		return shim.Error("marshal error ")
	}
	if err := stub.PutState(orderKey, orderByte1); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(orderByte1)
}

//添加温度，订单结构体 添加角色id 添加角色类型
func addTemperature(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := Vacunafiledchecking(stub, args, 3)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	var order VacunaTransaction
	if err := json.Unmarshal([]byte(args[0]), &order); err != nil {
		return shim.Error("unmarshal error")
	}
	//判断添加温度的角色
	if args[2] == SupplierKeyPrefix {
		order.Supplier = args[1]
	}
	if args[2] == LogisticsKeyPrefix {
		order.Logística = args[1]
	}
	if args[2] == HospitalKeyPrefix {
		order.Company = args[1]
	}
	//判断传入字段是否为空
	filedargs := []string{order.Id}
	filedres = Vacunafiledchecking(stub, filedargs, len(filedargs))
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	//查询订单
	orderKey, err := stub.CreateCompositeKey(OrderKeyPrefix, []string{order.Id})
	if err != nil {
		return shim.Error("create key error")
	}
	orderByte, err := stub.GetState(orderKey)
	if err != nil {
		return shim.Error("getstate error")
	}
	if len(orderByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "为查询到订单",
			Payload: nil,
		}
	}
	var order1 VacunaTransaction
	if err := json.Unmarshal(orderByte, &order1); err != nil {
		return shim.Error("unmarshal error ")
	}
	if order1.Status != OrderstatusShiped{
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "订单状态出错",
			Payload: nil,
		}
	}
	if order1.Company != order.Company && order1.Supplier != order.Supplier && order1.Logística != order.Logística {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "无权修改此订单",
			Payload: nil,
		}
	}
	order1.Temperature=append(order1.Temperature,order.Temperature[0])//添加温度结构体
//	同步更新单只疫苗的温度
	for i:=0;i<len(order1.VacunaId);i++{
		var vacu Vacuna
		vacuKey,err:=stub.CreateCompositeKey(VacunastatusPrefix,[]string{order1.VacunaId[i]})
		if err != nil {
			return shim.Error("create key error")
		}
		vacuByte,err:=stub.GetState(vacuKey)
		if err != nil {
			return shim.Error("get state error")
		}
		if len(vacuByte)==0{
			return pb.Response{
				Status:               shim.ERRORTHRESHOLD,
				Message:              "未查询到疫苗",
				Payload:              nil,
			}
		}
		if err:=json.Unmarshal(vacuByte,&vacu);err!=nil{
			return shim.Error("unmarshal error ")
		}
		vacu.Temperature=append(vacu.Temperature,order.Temperature[0])
		//	判断添加的温度是否超出疫苗温度阈值超出修改疫苗状态
		for i:=0;i<len(order.Temperature[0].Temps);i++{
			if order.Temperature[0].Temps[i]<vacu.Mintemperature{
				vacu.Status=VacunaStatus3
				vacu.Description="温度过低引起的变质"
			}
			if order.Temperature[0].Temps[i]>vacu.Maxtemperature{
				vacu.Status=VacunaStatus3
				vacu.Description="温度过高引起的变质"
			}

		}
		//序列化保存至账本
		vacuByte1,err:=json.Marshal(vacu)
		if err != nil {
			return shim.Error("marshal error")
		}
		if err:=stub.PutState(vacuKey,vacuByte1);err!=nil{
			return shim.Error("put state error ")
		}
	}
	//更新订单状态
	orderByte1, err := json.Marshal(order1)
	if err != nil {
		return shim.Error("marshal error")
	}
	if err := stub.PutState(orderKey, orderByte1); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(orderByte1)
}
//订单id 采购商id
func confirmReceiving(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := Vacunafiledchecking(stub, args,2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	//通过订单id查询订单
	orderKey, err := stub.CreateCompositeKey(OrderKeyPrefix, []string{args[0]})
	if err != nil {
		return shim.Error("create key error")
	}
	orderByte, err := stub.GetState(orderKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(orderByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未查询到相关订单",
			Payload: nil,
		}
	}
	//反序列化
	var order VacunaTransaction
	if err := json.Unmarshal(orderByte, &order); err != nil {
		return shim.Error("unmarshal error")
	}
	if order.Status != OrderstatusShiped {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "订单状态出错",
			Payload: nil,
		}
	}
	if order.Company != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "无权修改此订单",
			Payload: nil,
		}
	}
	order.Status = OrderstatusReceiving
	orderByte1, err := json.Marshal(order)
	if err != nil {
		return shim.Error("marshal error ")
	}
	if err := stub.PutState(orderKey, orderByte1); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(orderByte1)
}
//买家还款， {id:string,repayment_tx_number:string,tx_to_update:time.Time,company:string}
func repayOrder(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := Vacunafiledchecking(stub, args,1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	var order VacunaTransaction
	if err := json.Unmarshal([]byte(args[0]), &order); err != nil {
		return shim.Error("unmarshal error")
	}
	//判断传入字段是否为空
	filedargs := []string{order.Id, order.RepaymentTxNumber, order.Company}
	filedres = Vacunafiledchecking(stub, filedargs, len(filedargs))
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	//查询订单
	orderKey, err := stub.CreateCompositeKey(OrderKeyPrefix, []string{order.Id})
	if err != nil {
		return shim.Error("create key error")
	}
	orderByte, err := stub.GetState(orderKey)
	if err != nil {
		return shim.Error("getstate error")
	}
	if len(orderByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "为查询到订单",
			Payload: nil,
		}
	}
	var order1 VacunaTransaction
	if err := json.Unmarshal(orderByte, &order1); err != nil {
		return shim.Error("unmarshal error ")
	}
	if order1.Status != OrderstatusReceiving {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "订单状态出错",
			Payload: nil,
		}
	}
	if order1.Company != order.Company {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "无权修改此订单",
			Payload: nil,
		}
	}
	transferAccountsres := outtoin(stub, order1.FinancialOrg, FinancialOrgKeyPrefix, order1.Supplier, SupplierKeyPrefix, order1.Value)
	if transferAccountsres.Status != shim.OK {
		return pb.Response{
			Status:  transferAccountsres.Status,
			Message: transferAccountsres.Message,
			Payload: nil,
		}
	}
	order1.Status = OrderStatusRepay
	order1.RepaymentTxNumber=order.RepaymentTxNumber
	order1.RepayDate=order.RepayDate
	orderByte1, err := json.Marshal(order1)
	if err != nil {
		return shim.Error("marshal error")
	}
	if err := stub.PutState(orderKey, orderByte1); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(orderByte1)
}
//订单id 代付商id
func confirmrepay(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := Vacunafiledchecking(stub, args,2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	//通过订单id查询订单
	orderKey, err := stub.CreateCompositeKey(OrderKeyPrefix, []string{args[0]})
	if err != nil {
		return shim.Error("create key error")
	}
	orderByte, err := stub.GetState(orderKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(orderByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未查询到相关订单",
			Payload: nil,
		}
	}
	//反序列化
	var order VacunaTransaction
	if err := json.Unmarshal(orderByte, &order); err != nil {
		return shim.Error("unmarshal error")
	}
	if order.Status != OrderStatusRepay {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "订单状态出错",
			Payload: nil,
		}
	}
	if order.FinancialOrg != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "无权修改此订单",
			Payload: nil,
		}
	}
	order.Status = OrderStatusRepayed
	orderByte1, err := json.Marshal(order)
	if err != nil {
		return shim.Error("marshal error ")
	}
	if err := stub.PutState(orderKey, orderByte1); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(orderByte1)
}
//@Param:  { time:string }
func timeoutpay(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := Vacunafiledchecking(stub, args,1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	nowtime,err:=time.Parse("2006-01-02 15:04:05",args[0])
	if err != nil {
		return shim.Error("time parse error")
	}
	requst, err := stub.GetStateByPartialCompositeKey(OrderKeyPrefix, []string{})
	if err != nil {
		return shim.Error("查询所有订单出错")
	}
	defer requst.Close() //关闭结果集
	for requst.HasNext() {
		val, err := requst.Next()
		if err != nil {
			return shim.Error("next error")
		}
		var order VacunaTransaction
		if err := json.Unmarshal(val.GetValue(), &order); err != nil {
			return shim.Error("unmarshal error ")
		}
		if order.RepaymentDate.Unix() >= nowtime.Unix() { //超时自动还款
			transferAccountsres := outtoin(stub, order.Company, HospitalKeyPrefix, order.FinancialOrg,FinancialOrgKeyPrefix, order.Value)
			if transferAccountsres.Status != shim.OK {
				return pb.Response{
					Status:  transferAccountsres.Status,
					Message: transferAccountsres.Message,
					Payload: nil,
				}
			}
			order.Status = OrderStatusRepayed
			order.RepayDate = time.Now()
			orderKey, err := stub.CreateCompositeKey(OrderKeyPrefix, []string{order.Id})
			if err != nil {
				return shim.Error("create key error ")
			}
			orderByte, err := json.Marshal(order)
			if err != nil {
				return shim.Error("marshal error ")
			}
			if err := stub.PutState(orderKey, orderByte); err != nil {
				return shim.Error("putstate error")
			}
		}
	}
	//aa:=strconv.FormatInt(nowtime.Unix(),10)
	return shim.Success(nil)
}
//订单id
func queryOrder(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := Vacunafiledchecking(stub, args,1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	//通过订单id查询订单
	orderKey, err := stub.CreateCompositeKey(OrderKeyPrefix, []string{args[0]})
	if err != nil {
		return shim.Error("create key error")
	}
	orderByte, err := stub.GetState(orderKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(orderByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未查询到相关订单",
			Payload: nil,
		}
	}
	return shim.Success(orderByte)
}
//传入用户id
func queryRoleVacunas(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := Vacunafiledchecking(stub, args,1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	//查询所有疫苗
	request, err := stub.GetStateByPartialCompositeKey(VacunastatusPrefix, []string{})
	if err != nil {
		return shim.Error("查询所有疫苗出错")
	}
	defer request.Close() //关闭结果集
	var vacus []Vacuna
	for request.HasNext() {
		val, err := request.Next()
		if err != nil {
			return shim.Error("next error")
		}
		var vacu Vacuna
		if err := json.Unmarshal(val.GetValue(), &vacu); err != nil {
			return shim.Error("unmarshal error ")
		}
		if vacu.Propietario==args[0]{
			vacus=append(vacus, vacu)
		}
	}
	vacusByte,err:=json.Marshal(vacus)
	if err != nil {
		return shim.Error("marshal error")
	}
	return shim.Success(vacusByte)
}
//疫苗id
func queryVacuna(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := Vacunafiledchecking(stub, args,1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	//通过订单id查询疫苗
	vacuKey, err := stub.CreateCompositeKey(VacunastatusPrefix, []string{args[0]})
	if err != nil {
		return shim.Error("create key error")
	}
	vacuByte, err := stub.GetState(vacuKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(vacuByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未查询到相关疫苗",
			Payload: nil,
		}
	}
	return shim.Success(vacuByte)
}
//订单id
func queryOrderHistory(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := Vacunafiledchecking(stub, args,1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	orderKey,err:=stub.CreateCompositeKey(OrderKeyPrefix,[]string{args[0]})
	if err != nil {
		return shim.Error("create key error")
	}
	orderByte,err:=stub.GetState(orderKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(orderByte)==0{
		return pb.Response{
			Status:               shim.ERRORTHRESHOLD,
			Message:              "为查询到相关订单",
			Payload:              nil,
		}
	}
	requst,err:=stub.GetHistoryForKey(orderKey)
	if err != nil {
		return shim.Error(fmt.Sprintf("get order history error %s",err))
	}
	defer requst.Close()
	var buffer bytes.Buffer
	s := false
	buffer.WriteString("{")
	for requst.HasNext(){
		val,err := requst.Next()
		if err != nil {
			return shim.Error("gethistory error")
		}
		if s {
			buffer.WriteString(",")
		}
		buffer.WriteString("\"TxId\":")
		buffer.WriteString("\"")
		buffer.WriteString(val.TxId)
		buffer.WriteString("\"")

		buffer.WriteString(",\"value\":")
		if val.IsDelete{
			buffer.WriteString("null")
		}else {
			buffer.WriteString("\"")
			buffer.WriteString(val.TxId)
			buffer.WriteString("\"")
		}

		buffer.WriteString(",\"TimeStamp\":")
		buffer.WriteString("\"")
		buffer.WriteString(time.Unix(val.Timestamp.Seconds,int64(val.Timestamp.Nanos)).String())
		buffer.WriteString("\"")

		buffer.WriteString(",\"IsDelete\":")
		buffer.WriteString("\"")
		buffer.WriteString(strconv.FormatBool(val.IsDelete))
		buffer.WriteString("\"")
	}
	buffer.WriteString("}")
	return shim.Success(buffer.Bytes())
}

func Vacunafiledchecking(stub shim.ChaincodeStubInterface, args []string, length int) pb.Response {
	if len(args) != length {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "字段长度不符合要求",
			Payload: nil,
		}
	}
	for i := 0; i < len(args); i++ {
		if args[i] == "" {
			return pb.Response{
				Status:  shim.ERRORTHRESHOLD,
				Message: "字段为空",
				Payload: nil,
			}
		}
	}
	return shim.Success(nil)
}

func outtoin(stub shim.ChaincodeStubInterface, out, outtype, in, intype string, moneynum float64) pb.Response {
	if out == "" || outtype == "" || in == "" || intype == "" || moneynum < 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "传入参数不合法",
			Payload: nil,
		}
	}
	outKey, err := stub.CreateCompositeKey(outtype, []string{out})
	if err != nil {
		return shim.Error("create key error")
	}
	intKey, err := stub.CreateCompositeKey(intype, []string{in})
	if err != nil {
		return shim.Error("create key error")
	}
	//查询out
	outByte, err := stub.GetState(outKey)
	if err != nil {
		return shim.Error("get state error")
	}
	if len(outByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未查询到该角色",
			Payload: nil,
		}
	}
	var outrole Role
	if err := json.Unmarshal(outByte, &outrole); err != nil {
		return shim.Error("unmarshal error ")
	}
	//查询in
	inByte, err := stub.GetState(intKey)
	if err != nil {
		return shim.Error("get state error")
	}
	if len(inByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未查询到该角色",
			Payload: nil,
		}
	}
	var inrole Role
	if err := json.Unmarshal(outByte, &inrole); err != nil {
		return shim.Error("unmarshal error ")
	}
	if outrole.Banlance < moneynum {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "您的余额不足",
			Payload: nil,
		}
	}
	outrole.Banlance -= moneynum
	inrole.Banlance += moneynum
	//序列化保存至账本
	outByte1, err := json.Marshal(outrole)
	if err != nil {
		return shim.Error("marshal error")
	}
	if err := stub.PutState(outKey, outByte1); err != nil {
		return shim.Error("put state error")
	}
	inByte1, err := json.Marshal(inrole)
	if err != nil {
		return shim.Error("marshal error")
	}
	if err := stub.PutState(intKey, inByte1); err != nil {
		return shim.Error("put state error")
	}
	return shim.Success(nil)
}

func main() {
	err := shim.Start(new(Vacunacode))
	if err != nil {
		fmt.Sprintf("chaincode start error is %s", err)
	}
}
